package org.jlamp.boot.console;

import org.jlamp.boot.vm.VmUtils;
import org.jlamp.core.prop.JlampProp;
import org.jline.reader.*;
import org.jline.reader.impl.completer.StringsCompleter;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;

import java.io.IOError;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * CLI客户端操作
 *
 * @author zhangcs
 * @since 1.0
 */
public class JlampConsole {

    private static final PrintStream ps = System.out;

    /**
     * 提示符标识
     */
    private static final String SEPARATOR = "> ";

    /**
     * 提示符
     */
    private static String PROMPT = JlampProp.NAME + SEPARATOR;

    /**
     * 命令：退出
     */
    private static final String CMD_EXIT = "exit";

    /**
     * 命令：进程列表
     */
    private static final String CMD_LIST = "list";

    /**
     * 命令：帮助
     */
    private static final String CMD_HELP = "help";

    /**
     * 是否继续监听cli输入
     */
    private static AtomicBoolean running = new AtomicBoolean(true);

    public static void run() throws IOException {
        Terminal terminal = TerminalBuilder.builder()
                .system(true)
                .signalHandler(Terminal.SignalHandler.SIG_IGN)
                .nativeSignals(true)
                .build();

        // 指令
        Completer completer = new StringsCompleter(CMD_EXIT, CMD_LIST, CMD_HELP);

        LineReader lineReader = LineReaderBuilder.builder()
                .terminal(terminal)
                .completer(completer)
                .build();

        // 打印进程列表
        list();

        while (running.get()) {
            try {
                String line = lineReader.readLine(PROMPT);
                handleCommand(line);
            } catch (UserInterruptException | EndOfFileException | IOError e) {
                running.set(false);
            }
        }
    }

    /**
     * 处理命令内容
     *
     * @param line 命令字符串
     */
    private static void handleCommand(String line) {
        if (line != null && line.length() > 0) {
            line = line.toLowerCase(Locale.ENGLISH);
        }

        if (CMD_EXIT.equals(line)) {
            // 退出
            exit();
            return;
        }

        if (CMD_HELP.equals(line)) {
            help();
            return;
        }

        if (CMD_LIST.equals(line)) {
            // 打印进程列表
            list();
            return;
        }

        List<String> ids = VmUtils.ids();
        if (!ids.contains(line)) {
            help();
            return;
        }

        boolean status = VmUtils.attach(line);
        if (status) {
            PROMPT = line + SEPARATOR;
        }
    }

    /**
     * 打印帮助信息
     */
    private static void help() {
        ps.println("usage: list | exit | {pid}");
    }

    /**
     * 打印进程列表
     */
    private static void list() {
        List<String> processList = VmUtils.list();
        ps.println("Select the process id of the Java Virtual Machine:\n"
                + String.join("\n", processList));
    }

    /**
     * 退出
     */
    private static void exit() {
        if (VmUtils.isAttaching()) {
            boolean detachStatus = VmUtils.detach();
            if (detachStatus) {
                PROMPT = JlampProp.NAME + SEPARATOR;
            }
            return;
        }
        System.exit(0);
    }

}
